<template>
  <view style="position: relative;" @tap="handleWheel">
    <view ref="box" :style="boxStyle" @touchstart="handleTouchStart" @touchmove="handleTouchMove">
      <slot />
    </view>
  </view>
</template>

<script>
import taro from '@tarojs/taro'
/** 初始缩放值 */
const INIT_SCALE_NUM = 100
/** 最大缩放值 */
const MAX_SCALE_NUM = 200
/** 最小缩放值 */
const MIN_SCALE_NUM = 10
/** 初始x位置 */
const INIT_POSITIONX = 0
/** 初始x位置 */
const INIT_POSITIONY = 0
/** 初始旋转位置 */
const INIT_ROTATE_NUM = 0
const height = 400 // 临时高度
const positionMixin = {
  data () {
    return {
      upPositionX: INIT_POSITIONX, // 移动前x坐标
      upPositionY: INIT_POSITIONY, // 移动前y坐标
      positionX: INIT_POSITIONX,
      positionY: INIT_POSITIONY,
    }
  },
  computed: {
    maxPositionX () {
      return taro.getSystemInfoSync().screenWidth
    },
    maxPositionY () {
      return height
    }
  },
  methods: {
    /**移动前*/
    handleTouchStart (e) {
      this.upPositionX = e.touches[0].clientX
      this.upPositionY = e.touches[0].clientY
    },
    /**移动后 */
    handleTouchMove (e) {
      const x = e.touches[0].clientX
      const y = e.touches[0].clientY
      const currentX = this.positionX + x - this.upPositionX
      const currentY = this.positionY + y - this.upPositionY
      if (currentX > this.maxPositionX) return
      if (currentY > this.maxPositionY) return
      this.upPositionX = currentX
      this.upPositionY = currentY
      this.positionX = currentX
      this.positionY = currentY
    },
    /**重置位置 */
    resetPosition () {
      this.positionX = INIT_POSITIONX
      this.positionY = INIT_POSITIONY
    }
  }
}
/** 缩放 */
const scaleMixin = {
  props: {
    /** 
     * 每次缩放比例
     * 范围: 0-100
     */
    scaleStep: {
      type: Number,
      default: 10
    },
  },
  data () {
    return {
      scaleNum: INIT_SCALE_NUM,
    }
  },
  watch: {
    scaleNum () {
      this.$emit('scaleChange', this.scaleNum)
    },
  },
  methods: {
    /** 定义的鼠标滚动事件 */
    handleWheel (e) {
      const boxDOM = this.$refs.box
      if (e.deltaY < 0) {
        this.setScale(this.scaleStep)
      } else {
        this.setScale(-this.scaleStep)
      }
    },
    /** 重置缩放 */
    resetScale () {
      this.scaleNum = INIT_SCALE_NUM
    },
    /**
     * 设置缩放
     * @param {number?} stepNum 步骤值
     * @param {boolean?} override 是否覆盖
    */
    setScale (stepNum, override = false) {
      if (stepNum === undefined) stepNum = this.scaleStep
      if (override) {
        this.scaleNum = stepNum
      } else {
        this.scaleNum += stepNum
      }
      /** 越界判断 */
      if (this.scaleNum > MAX_SCALE_NUM) {
        this.scaleNum = MAX_SCALE_NUM
      } else if (this.scaleNum < MIN_SCALE_NUM) {
        this.scaleNum = MIN_SCALE_NUM
      }
    },
  },
}
/** 旋转 */
const rotateMixin = {
  props: {
    /** 
     * 每次旋转比例
     * 范围: 0-360
     */
    rotateStep: {
      type: Number,
      default: 45
    },
  },
  data () {
    return {
      rotateNum: INIT_ROTATE_NUM,
    }
  },
  methods: {
    /** 重置旋转 */
    resetrotate () {
      this.rotateNum = INIT_ROTATE_NUM
    },
    /**
     * 设置旋转
     * @param {number?} stepNum 步骤值
     * @param {boolean?} override 是否覆盖
    */
    setRotate (stepNum, override = false) {
      if (stepNum === undefined) stepNum = this.rotateStep
      if (override) {
        this.rotateNum = stepNum
      } else {
        this.rotateNum += stepNum
      }
    },
  },
}
export default {
  name: 'BoxCommonfeature',
  components: {},
  mixins: [positionMixin, scaleMixin, rotateMixin],
  data () {
    return {
    };
  },
  computed: {
    boxStyle () {
      return {
        position: 'absolute',
        transition: 'transform 1s ease 0s',
        left: this.positionX + 'px',
        top: this.positionY + 'px',
        width: '100%',
        height: '100%',
        transform: `scale(${this.scaleNum / 100}) rotate(${this.rotateNum}deg)`,
      }
    }
  },
  watch: {},
  methods: {
    resetAll () {
      this.resetPosition()
      this.resetScale()
      this.resetrotate()
    }
  }
}
</script>
<style>
</style>